查看原文
其他

“命令式” vs “声明式”? VMWare Project Pacific小探

hotcan 热罐小角 2022-07-03

点击蓝字关注,一起探讨更好玩的IT世界

 

上周跟VMware聊他们的新产品,被强调了多次“声明式”的优点,让我回想起了计算机编程语言中的种种分类,为了回忆我那许久不用的专业知识,周末我花了点时间复习了一下当年的功课,同时也研究了一下VMware的Project Pacific到底做了啥。




编程范式(Programming Paradigm)



  

按照Wikipedia上的定义,编程范式主要有两种,一种叫命令式(Imperative),主要定义机器执行过程,即指导机器改变状态,比如像C,Fortran或者Pascal这种面向过程的语言以及像C++,Java这种面向对象的语言。

 

还有一种叫做声明式(Declarative),主要是定义机器的最终状态而不是执行过程,包括三类:


  1. 函数式(Functional),结果定义为一系列函数的值。

  2. 逻辑式(Logic),结果定义为一系列事实或规则的结果。

  3. 数学(Mathematics), 结果定义为一系列优化问题的结果。

 

目前很多新的编程语言都支持多种编程范式,比如C#里的LINQ,Java 8 里的Lambda表达式,都是声明式的。早期还有一种语言叫LISP,是著名的函数式编程语言。

 

Wikipedia上有一张图我看得不是特别明白,来自比利时鲁汶大学(Catholic University of Louvain)教授Peter Van Roy的文章"Programming Paradigms: What Every Programmer Should Know",看上去是对编程语言更学术的分类,看着很深奥的样子,我就不仔细研究了。

 


 

在思考这个问题的时候,我下意识的反应是《圣经》里上帝的行为,一种是命令式的,一种是声明式的。


  • 命令式:神说,我们要照着我们的形像,按着我们的样式造人,使他们管理海里的鱼,空中的鸟,地上的牲畜,和全地,并地上所爬的一切昆虫。”




  •  声明式“神说,要有光,就有了光。”



 

 

好吧,回到正题。从代码的角度而言,声明式的代码看上去更结果导向一些,而命令式代码看上去更加繁杂一些。现在比较有经验的程序员可能更喜欢用声明式的方式来编写,让代码结构更清楚,犯错的概率变小,降低调试的成本。

 

我们来看一下C#里的两种代码风格:

 

C#命令式代码:


C#声明式代码:



Project Pacific具体做了什么?



凡事不自己摸一摸就没有发言权,对一些新的产品如果不去看看技术文档,就不能说自己知道是什么。毕竟这个行业新名词太多,一不当心就会跳坑里被忽悠。所以我又花了点时间去看了一下VMware Project Pacific的技术文档,有两张图的印象比较深刻,一张是这个:

 


这是把Kubernetes集成到了vSphere当中,可以直接在vSphere上运行容器,叫Native Pods,效率得到了提升,比Linux VM上快30%,比裸机上快8%。还可以直接用vSphere的管理界面起k8s的集群,把虚拟机和容器提升到了一个水平线上。

 

好吧,前几年在容器和OpenStack打架的时候VMware还闭口不谈容器,现在看上去是全面拥抱容器技术了。这个选择和大多数云厂商是一样的,真为OpenStack感到伤心。

 

另外一张我印象比较深刻图是这个:

 


中间部分是新时代应用的核心,下面部分画的是无服务器计算,即FaaS。上面部分是各种传统节点,控制平面和应用程序,节点上可以跑虚拟机或者容器,里面可能跑着数据库,也可能是一些旧应用。两边是基于Yaml格式的一些声明式定义,包括类型,元数据,版本等等。通过它我们可以用Yaml格式定义相关的资源,发布应用之后,vSphere会帮我们创建资源,最终统一管理。

 

这是典型的声明式的写法,当然类似的写法有很多,包括AWS CloudFormation基于Json格式写法,还有Microsoft Azure ARM。一些脚本语言用Yaml的会多一些。关于Yaml和Json的区别,网上资料很多,这里我就不多说了。

 

鉴于Project Pacific是对vSphere加了Kubernetes的支持,而且这个声明式的定义看着是标准的Yaml格式,所以我猜,VMware应该是基于Kubernetes 的自定义资源类型(Custom Resource Definition, CRD),扩展了VMware的资源,在统一的平面上支持了Pod和VM的管理和互相通讯。

 

Kubernetes的CRD可以扩展资源,通过Yaml进行声明,实现可以用golang,写完以后通过kubectl命令调用相关的REST API创建自定义资源,并进行CRUD操作。当然我以前也不知道k8s支持这个骚操作,所以又进一步去看了看github上的一个代码例子: 

https://github.com/kubernetes/sample-controller

 


 

在这个例子里,演示了三件事:

  1. 在k8s里注册一个Foo类型的自定义资源(CRD)

  2. 创建Foo类型CRD的实例

  3. 通过资源上的控制器,操作创建、更新、删除事件。

 

写完代码以后,可以通过kubectl调用相关REST API创建自定义资源并部署:



具体的实现可以放在pkg目录下的register.go和types.go里,还有自动代码生成的工具,可以实现基本操作。

 

再看看Project Pacific,工具是一样的,都是kubectl,命令也大同小异。 


做完之后,可以直接在vSphere里同时操作k8s集群,容器和虚拟机。支持安全集成,k8s的事件也可以统一收集上来一并展示。

 


所以Project Pacific通过定义k8s的CRD,用Yaml对资源进行了扩展,能够统一编排容器和虚拟机,提升了用户的体验。


所以想想,k8s也是挺牛的,可以让那么多厂商跟随它的脚步,基于它定义的标准,扩展商业软件产品。这在过去商业软件纵横天下的时代,是无法想象的。


END


曾今,伏案只识技术世界

而后,抬头遍历创业之艰

现如今

不惑之年

以创业者眼光,再探技术世界

长按二维码关注,一起窥探云上世界

🔻


关于作者

Hotcan,80后技术老炮儿

云计算和数字化技术的创业者

创业公司被收购之后,负责云和数字化转型业务



历史文章


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存